package org.emfjson.couchdb.streams;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter.Saveable;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.emfjson.couchdb.client.CouchClient;
import org.emfjson.couchdb.client.CouchDocument;
import org.emfjson.couchdb.client.DB;
import org.emfjson.jackson.JacksonOptions;
import org.emfjson.jackson.module.EMFModule;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;
public class CouchOutputStream extends ByteArrayOutputStream implements Saveable {
private final URI uri;
private final Map<?, ?> options;
private final CouchClient client;
public CouchOutputStream(CouchClient client, URI uri, Map<?, ?> options) {
this.client = client;
this.uri = uri;
this.options = options;
}
@Override
public void saveResource(Resource resource) throws IOException {
final String dbName = uri.segment(0);
final String docName = uri.segment(1);
final DB db = client.db(dbName);
if (!db.exist()) {
db.create();
}
if (docName == null) {
throw new IOException("Cannot load undefined document");
}
final CouchDocument doc = db.doc(docName);
final JsonNode status = doc.create(toJson(resource));
if (status != null && status.has("ok")) {
if (status.get("ok").asBoolean()) {
String rev = status.get("rev").asText();
URI newURI = resource.getURI().appendQuery("rev=" + rev);
resource.setURI(newURI);
}
}
}
private JsonNode toJson(Resource resource) {
ResourceSet resourceSet = resource.getResourceSet();
if (resourceSet == null) {
resourceSet = new ResourceSetImpl();
}
final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new EMFModule(resourceSet, JacksonOptions.from(options)));
final JsonNode contents = mapper.valueToTree(resource);
final ObjectNode resourceNode = mapper.createObjectNode();
final String id = uri.segment(1);
resourceNode.put("_id", id);
resourceNode.set("contents", contents);
return resourceNode;
}
}